#pragma once

#include <stdint.h>
#include "Part.h"
#include "base/core/object_pool.h"
enum enTitleFinishType
{
	enTitleFinishType_ChangeAttr		= 1,	//属性值达到某值达成称号条件
	enTitleFinishType_UseItem			= 2,	//使用物品
	enTitleFinishType_GetGem			= 3,	//获取宝石数量
	enTitleFinishType_Achieve			= 4,	//完成成就
	enTitleFinishType_AtttackValue		= 5,	//功击力达到多少点，因为要分职业，固和1分开
	enTitleFinishType_PetFightPower		= 6,	//精灵功击力
	enTitleFinishType_KillPlayer		= 7,	//击杀玩家
	enTitleFinishType_DeadNum			= 8,	//死亡次数
	enTitleFinishType_ArenaLevel		= 9,	//竞技场层数
	enTitleFinishType_KillCampPlayer	= 10,	//击杀阵营人数
	enTitleFinishType_Collect			= 11,	//采集等级
	enTitleFinishType_Forge				= 12,	//锻造等级
	enTitleFinishType_GetEquip			= 13,	//获取装备
	enTitleFinishType_FinishActivity	= 14,	//完成活动次数
	enTitleFinishType_GodLevel			= 15,   //神格升级 
	enTitleFinishType_FinishRefineEquip = 16,	//装备精炼
	enTitleRankingList_Fight			= 24,	//战力排行称号
	enTitleRankingList_Level			= 25,	//等级排行称号
	enTitleFinishType_SoundTalk			= 26,	//语音聊天到达指定条数
	enTitleFinishType_Refine_Fail		= 27,	//精炼失败
	enTitleFinishType_Task				= 28,	//完成指定任务获得称号
	enTitleFinishType_Explore_Map		= 29,	//探索地图
	enTitleFinishType_Trigger_Snare		= 30,	//挖宝触发陷阱
	enTitleFinishType_ArenaLevel_SomeTime = 31,	//竞技场连续天数达到指定等级
	enTitleFinishType_KillMonster		  = 32,	//击杀指定ID的怪物指定数量
	enTitleFinishType_AnyCollectByWork_Skill = 33,	//任意采集副业技能达到指定等级
	enTitleFinishType_AnyMakeByWork_Skill    = 34,	//任意制造副业技能达到指定等级
	enTitleFinishType_Cooking				 = 35,	//烹饪指定等级的食物指定数量
	enTitleFinishType_Making_Drug			 = 36,	//制造指定等级的药品指定数量
	enTitleFinishType_Talking_NPC			 = 37,	//连续指定天数和指定NPC交谈
  
	enTitleFinishType_Add_Achieve_Progress = 100,		//增加成就进度，上面是和配置表一一对应，下面是内部用
};



class stTitle
{
public:
	stTitle()
	{
		_ID = 0;
		_StartCanUseTime = 0;
		_currentParam = 0;
		_key = 0;
	}
	virtual void SaveDB(CharacterTitleSaveData*pSave)
	{
		if (_StartCanUseTime > 0 || _currentParam > 0)
		{
			//需要保存
			CharacterTitleInfo* pInfo = pSave->add_titeldata();
			pInfo->set_id(_ID);
			pInfo->set_param(_currentParam);
			pInfo->set_starttime(_StartCanUseTime);
		}
	}

	virtual void Init(CharacterTitleInfo*pInfo)
	{
		_currentParam = pInfo->param();
		_StartCanUseTime = pInfo->starttime();
	}

	uint32_t	_ID;					//称号ID
	uint64_t    _StartCanUseTime;		//可以使用时间
	uint32_t	_currentParam;			//当前达到参数值
	int32_t    _key;					//关键参数值，根据类型来表示不同意义
};

//记录进过的地图数量的称号
class stEnterMapTitle : public stTitle
{
public:
	stEnterMapTitle():stTitle()
	{
		vMap.clear();
	}

	void SaveDB(CharacterTitleSaveData*pSave)
	{
		if (_StartCanUseTime > 0 || _currentParam > 0)
		{
			CharacterTitleInfo* pInfo = pSave->add_titeldata();
			pInfo->set_id(_ID);
			pInfo->set_param(_currentParam);
			pInfo->set_starttime(_StartCanUseTime);
			for (int i = 0; i < (int)vMap.size();++i)
			{
				pInfo->add_mapid(vMap[i]);
			}
		}
	}

	void Init(CharacterTitleInfo*pInfo)
	{
		_currentParam = pInfo->param();
		_StartCanUseTime = pInfo->starttime();
		for (int i = 0; i < pInfo->mapid_size(); ++i)
		{
			vMap.push_back(pInfo->mapid(i));
		}
	}

	std::vector<uint32_t> vMap;
};



//称号部件
class TitlePart : public Part
{
	typedef bool(TitlePart::*pFunc)(const char*, uint32_t);
	typedef std::unordered_map<uint32_t, pFunc> mapMsgFunc;	
	typedef std::map<uint32_t, stTitle*> mapTitle;
	typedef std::map<uint32_t, std::vector<uint32_t> > mapAttrTitle; //记录属性称号的属性ID和称号ID
	typedef std::map<uint32_t, std::vector<uint32_t> > mapTypeTitle; //称号按类型记录的map
public:
	TitlePart();
	virtual ~TitlePart();
public:
	//生物init调用
	virtual bool Init(Creature *pMaster, uint32_t partType, CharacterDBInfo* pCharacterDB = nullptr);
	//生物uint调用
	virtual bool UnInit();
public:
	//事件和时间调用的直接用下面的就行了
	virtual void OnExecute(uint16_t nEventID, uint64_t nSrcID, uint8_t bySrcType, void *pContext, int32_t nLen);
	virtual void OnTimer(uint32_t nTimerId);
	//客户端消息入口
	virtual bool OnMsgHandle(uint32_t cmd, const char* data, uint32_t len);
	//生物update
	virtual void Update(uint64_t tick);
	//生物存储DB部件入口
	virtual bool SaveDB(CharacterDBInfo& characterDB);
	//生物登入同步客户度数据入口
	virtual bool SynOnLogin(PlayerClientInfo& playerInfo);
	//称号参数改变
	//后面跟参数，可能是总数量，也可能是改数量，也可能都不用
	//param1表示是具体的物品或是类型id,后面两参数只表示数量
	void OnTitleParamChange(enTitleFinishType type, int32_t param1, uint32_t Allparam = 0, uint32_t changeParam = 0);
	//判断该称号是否已完成
	bool JudgeTitle(const TitleTitleCfgInfo * pConfig, int32_t param1, stTitle & stTile, uint32_t Allparam, uint32_t changeParam);
	//完成条件判断
	//param1  事件传过来的参数
	//orderNum 用于判断是否完成的配置表参数
	//Allparam  事件传来的进度，大于0表示是传的当前值
	//changeParam 事件传来的进度，大于0表示传来的改变值
	bool JudgeFinish(const TitleTitleCfgInfo * pConfig, int32_t param1, stTitle & stTile, int32_t orderNum, uint32_t Allparam, uint32_t changeParam);
	//加称号属性,id大于0表示添加，等于0表示清空
	bool AddTitleAttr(uint32_t titleID=0);
	void SendEnableTitle(uint32_t TitleID);
	//重置公会和阵营相关称号
	//uint32_t value 公会职位,如果为0则清空，不为0，则现有职位相等不清空，否则清空
	bool ResetClanTitle(uint32_t value);
	bool ResetCampTitle(uint32_t value);
	bool ResetOneAttrAllTitle(uint32_t PANum, uint32_t value);
	//处理属性相关称号
	void DoAttrTitle(uint32_t PANum,int64_t nValue);
	//完成称号，给外部调用
	//int64_t leftValidTime 称号剩余有效时间，单位秒 0表示永久称号
	void FinishTitle(uint32_t titleID,int64_t leftValidTime);

	//添加排名活动称号
	void AddRankingList(uint32_t type, uint32_t index);
	//删除一个称号
	void DeleteTitle(stTitle*pTitle);
public:
	bool OnGetTitlelist(const char* data, uint32_t len);
	bool OnUseTitle(const char* data, uint32_t len);
	bool OnAddAttrTitle(const char* data, uint32_t len);
	bool OnUseTitleCancle(const char* data, uint32_t len);
	bool OnAddAttrTitleCancle(const char* data, uint32_t len);
private:
	mapTitle m_mapTitle;	//称号数据
	mapAttrTitle m_mapAttrTitle; //属性相关称号
	mapMsgFunc m_mapMsgfunc; //消息队列
	mapTypeTitle m_mapTypeTitle; //按类型分开,不包括属性相关的，属性的单独处理了
	ObjectPool<stTitle> *m_pTitlePool;	//称号缓存
	ObjectPool<stEnterMapTitle> *m_pTitleMapPool;	//称号缓存
	uint32_t m_nOpenLevel;
};
